﻿//**********************************************************
//Copyright(C)2010 By 波特商网公司 版权所有。
//
//文件名：
//文件功能：自定义控件
//
//创建标识：陈博生 || 2011-05-24
//
//修改标识： 陈博生 || 2011-06-17
//修改描述：修改输入位数小于检索位数是，触发AfterSelect事件 
//**********************************************************

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace Hmc.IM.Common.UserControls
{
    /// <summary>
    /// TextBox+ComboBox组合，类似百度搜索框
    /// </summary>
    public class ucTextComboBox : ucTextBox  
    {
        #region 属性声明

        /// <summary>
        /// 网格控件
        /// </summary>
        private System.Windows.Forms.DataGridView dgvGrid;
        private System.Windows.Forms.DataGridViewTextBoxColumn colMerchantId;
        private System.Windows.Forms.DataGridViewTextBoxColumn colMerchantName;

        private bool dropdown = false;
        /// <summary>
        /// 是点击或者Enter选择值
        /// </summary>
        private bool isEnterOrClick = false;
        private bool _selectText = false;

        private int _searchLength = 3;
        /// <summary>
        /// 开始搜索的起始长度
        /// </summary>
        [Category("行为"),
        Description("获得或设置一个值，输入编码多少位开始查询"),
        DefaultValue(3)]
        public int SearchLength
        {
            get { return _searchLength; }
            set { _searchLength = value; }
        }

        /// <summary>
        /// 与控件关联的文本
        /// </summary>
        [Category("外观"),
        Description("与控件关联的文本"),
        DefaultValue("")]
        public override string Text
        {
            get
            {
                return base.Text;
            }
            set
            {
                base.Text = value;
                if (!_selectText)
                {
                    //DataBind();
                    //GetValue();
                }
            }
        }

        private object _selectedItem;

        /// <summary>
        /// 选择的数据对象（米海波 2011.06.17）
        /// </summary>
        public object SelectedItem
        {
            get { return _selectedItem; }
            set { _selectedItem = value; }
        }

        private object _dataSourse;
        /// <summary>
        /// 数据源
        /// </summary>
        public object DataSourse
        {
            get { return _dataSourse; }
            set { _dataSourse = value; }
        }

        private string _displayMember;
        /// <summary>
        /// 编码
        /// </summary>
        public string DisplayMember
        {
            set
            {
                _displayMember = value;
                if (!DesignMode)
                    this.colMerchantId.DataPropertyName = _displayMember;
            }
        }
        private string _valueMember;
        /// <summary>
        /// 名称
        /// </summary>
        public string ValueMember
        {
            set
            {
                _valueMember = value;
                if (!DesignMode)
                    this.colMerchantName.DataPropertyName = _valueMember;

            }
        }

        private string _selectedValue;
        /// <summary>
        /// 选择的对象
        /// </summary>
        public string SelectedValue
        {
            get { return _selectedValue; }        
        }

        /// <summary>
        /// 
        /// </summary>
        [Description("设置数据事件")]
        public event Action DataSourceBind;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public delegate void AfterSelectHandler(object sender, CancelEventArgs e);
        /// <summary>
        /// 
        /// </summary>
        [Description("用户选择记录后触发的事件")]
        public event AfterSelectHandler AfterSelect;

        private bool _secondVisible = true;
        /// <summary>
        /// 第二列是否可见
        /// </summary>
        [Category("行为"),
        Description("获得或设置一个值，第二列是否可见"),
        DefaultValue(true)]
        public bool SecondVisible
        {
            get { return _secondVisible; }
            set { _secondVisible = value; }
        }
        #endregion

        /// <summary>
        /// 构造函数
        /// </summary>
        public ucTextComboBox()
        {
            InitializeComponent();
        }

        #region 设计器变量
        /// <summary> 
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary> 
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源，为 true；否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                dgvGrid.Dispose();
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void InitializeComponent()
        {
            this.dgvGrid = new System.Windows.Forms.DataGridView();
            this.colMerchantId = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.colMerchantName = new System.Windows.Forms.DataGridViewTextBoxColumn();

            // 
            // DataGridView
            // 
            this.dgvGrid.AllowUserToResizeColumns = false;
            this.dgvGrid.AutoGenerateColumns = false;
            this.dgvGrid.AllowUserToResizeRows = false;
            this.dgvGrid.AllowUserToAddRows = false;
            this.dgvGrid.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
            | System.Windows.Forms.AnchorStyles.Right)));
            this.dgvGrid.BackgroundColor = System.Drawing.Color.White;
            this.dgvGrid.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None;
            this.dgvGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dgvGrid.ColumnHeadersVisible = false;
            this.dgvGrid.MultiSelect = false;
            this.dgvGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.colMerchantId,
            this.colMerchantName});
            this.dgvGrid.GridColor = System.Drawing.SystemColors.Control;
            this.dgvGrid.Location = new System.Drawing.Point(3, 27);
            this.dgvGrid.Name = "DataGridView";
            this.dgvGrid.ReadOnly = true;
            this.dgvGrid.RowHeadersVisible = false;
            this.dgvGrid.RowTemplate.Height = 23;
            this.dgvGrid.RowTemplate.Resizable = DataGridViewTriState.True;
            this.dgvGrid.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.dgvGrid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
            this.dgvGrid.Size = new System.Drawing.Size(194, 150);
            this.dgvGrid.TabIndex = 1;
            this.dgvGrid.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(dgvGrid_CellDoubleClick);

            // 
            // colMerchantId
            // 
            this.colMerchantId.DataPropertyName = "MerchantId";
            this.colMerchantId.HeaderText = "编码";
            this.colMerchantId.Name = "colMerchantId";
            this.colMerchantId.ReadOnly = true;
            // 
            // colMerchantName
            // 
            this.colMerchantName.DataPropertyName = "MerchantName";
            this.colMerchantName.HeaderText = "名称";
            this.colMerchantName.Name = "colMerchantName";
            this.colMerchantName.ReadOnly = true;  
          
        }

        #endregion
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void dgvGrid_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            isEnterOrClick = true;
            GetValue();
            this.Focus();
        }

        /// <summary>
        /// 取得选择的值
        /// </summary>
        private void GetValue()
        {
            CancelEventArgs e = new CancelEventArgs(true);
            string oldtext = this.Text;
            _selectText = true;

            if (dgvGrid.RowCount == 0 || this.TextTrimLength == 0 || _dataSourse == null)
            {
                this.Text = string.Empty;
                this.SelectedItem = null;
                _selectedValue = null;
                if (AfterSelect != null)
                {
                    AfterSelect(this, e);
                }  
                return;
            }

            _selectedValue = dgvGrid.SelectedRows[0].Cells[1].Value.ToString();
            this.Text = dgvGrid.SelectedRows[0].Cells[0].Value.ToString();
            this.SelectedItem = dgvGrid.SelectedRows[0].DataBoundItem;
         

            if (AfterSelect != null)
            {    
                AfterSelect(this, e);
            }        

            if (!e.Cancel)
            {
                this.SelectedItem = null;
                _selectedValue = null;
                this.Text = oldtext;
            }
            HideDropDown();
          
        }

        /// <summary>
        /// 隐藏下拉列表
        /// </summary>
        private void HideDropDown()
        {
            this.dgvGrid.Parent = null;
            this.dgvGrid.Visible = false;
            dropdown = false;
        }

        /// <summary>
        /// 文字去空格的长度
        /// </summary>
        internal int TextTrimLength
        {
            get
            {
                return this.Text.Trim().Length;
            }
        }

        /// <summary>
        /// 重写控件KeyUp事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnKeyUp(KeyEventArgs e)
        {
            base.OnKeyUp(e);
            if (e.KeyCode != Keys.Up
                && e.KeyCode != Keys.Enter
                && e.KeyCode != Keys.Down)
            {
                if (this.TextTrimLength >= _searchLength)
                {
                    DataBind();
                    OnResize(EventArgs.Empty);

                    if (_dataSourse == null ||
                        (_dataSourse as System.Collections.IList).Count == 0)
                    {
                        HideDropDown();
                    }
                }
                else
                {
                    dgvGrid.DataSource = null;
                    OnResize(EventArgs.Empty);
                    HideDropDown();
                }
            }
        }

        /// <summary>
        /// 重写离开控件事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLeave(EventArgs e)
        {
            base.OnLeave(e);
            if (!dgvGrid.Focused && dropdown)
            {
                HideDropDown();
            }
            if (this.TextTrimLength < _searchLength)
            {
                this.Text = string.Empty;
                _selectedValue = null;
                this.SelectedItem = null;
                if (AfterSelect != null && dgvGrid.SelectedRows.Count > 0)
                {
                    this.SelectedItem = dgvGrid.SelectedRows[0].DataBoundItem;
                    AfterSelect(this, new CancelEventArgs(true));
                }
            }
            else if (this.TextTrimLength >= _searchLength && !dropdown)
            {
                if (isEnterOrClick)
                    return;
                GetValue();
            }
        }

        /// <summary>
        /// 重写键盘按下键事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnKeyDown(System.Windows.Forms.KeyEventArgs e)
        {
            base.OnKeyDown(e);
            #region ↑↓ 和enter 键控制
            switch (e.KeyCode)
            {
                case Keys.Down:
                    if (dgvGrid.Rows.Count > 0)
                    {
                        int currentRowIndex = dgvGrid.SelectedRows.Count > 0 ? dgvGrid.SelectedRows[0].Index : -1;
                        if (currentRowIndex == dgvGrid.Rows.Count - 1)
                        {
                            //在最后一行按向下键
                            dgvGrid.FirstDisplayedScrollingRowIndex = 0;
                            dgvGrid.Rows[dgvGrid.Rows.Count - 1].Selected = false;
                            dgvGrid.Rows[0].Selected = true;
                        }
                        else
                        {
                            //在其它行按向下键
                            if (dgvGrid.FirstDisplayedScrollingRowIndex + dgvGrid.DisplayedRowCount(false) - 1 == currentRowIndex)
                            {
                                //只有当前行是最后一行时才向下滚动
                                dgvGrid.FirstDisplayedScrollingRowIndex = dgvGrid.FirstDisplayedScrollingRowIndex + 1;
                            }
                            dgvGrid.Rows[currentRowIndex].Selected = false;
                            dgvGrid.Rows[currentRowIndex + 1].Selected = true;
                        }
                    }
                    e.Handled = true;
                    break;
                case Keys.Up:
                    if (dgvGrid.Rows.Count > 0)
                    {
                        int currentRowIndex = dgvGrid.SelectedRows.Count > 0 ? dgvGrid.SelectedRows[0].Index : dgvGrid.Rows.Count;
                        if (currentRowIndex == 0)
                        {
                            //在第一行按向上键,选中最后一行
                            dgvGrid.FirstDisplayedScrollingRowIndex = dgvGrid.Rows.Count - 1;
                            dgvGrid.Rows[0].Selected = false;
                            dgvGrid.Rows[dgvGrid.Rows.Count - 1].Selected = true;
                        }
                        else
                        {
                            //在其它行按向上键
                            if (dgvGrid.FirstDisplayedScrollingRowIndex == currentRowIndex)
                            {
                                dgvGrid.FirstDisplayedScrollingRowIndex = dgvGrid.FirstDisplayedScrollingRowIndex - 1;
                            }
                            dgvGrid.Rows[currentRowIndex].Selected = false;
                            dgvGrid.Rows[currentRowIndex - 1].Selected = true;
                        }
                    }
                    e.Handled = true;
                    break;
                case Keys.Enter:
                    //回车选择DataGridView的值
                    isEnterOrClick = true;
                    GetValue();
                    this.Focus();
                    break;
                default:
                    ShowDropDown();
                    isEnterOrClick = false;
                    break;
            }
            #endregion
           
        }

        /// <summary>
        /// 重写调整大小事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            LayoutControls();
        }

        /// <summary>
        /// 布局所有控件，让TextBox尺寸适应容器尺寸
        /// </summary>
        private void LayoutControls()
        {
            int rowCount = dgvGrid.RowCount >= 10 ? 10 : dgvGrid.RowCount;
            dgvGrid.Height = dgvGrid.RowTemplate.Height * rowCount + (rowCount == 0 ? 0 : 2);
            if (SecondVisible)
            {
                dgvGrid.Width = 200;
                colMerchantName.Visible = true;
            }
            else
            {
                colMerchantName.Visible = false;
                colMerchantId.Width = this.Width;
                dgvGrid.Width = this.Width;
            }
        }

        /// <summary>
        /// 显示下拉列表
        /// </summary>
        private void ShowDropDown()
        {
            if (this.Parent == null)
                return;
            Point pos = new Point(this.Left, this.Bottom - 1);

            Point parentPos = this.Parent.PointToScreen(this.Parent.Location);
            Point topParentPos = this.TopLevelControl.PointToScreen(this.Parent.Location);
            pos.Offset(parentPos.X - topParentPos.X, parentPos.Y - topParentPos.Y);
            if ((pos.Y + this.dgvGrid.Height) > this.TopLevelControl.ClientRectangle.Height)
            {
                pos.Y -= (this.Height + this.dgvGrid.Height);
                if (pos.Y < 0)
                {
                    pos.Y = (this.TopLevelControl.ClientRectangle.Height - this.dgvGrid.Height);
                }
            }

            // 尝试停靠,如果右边超过顶级窗口的客户区，则将控件向左移动，并紧靠在顶级窗口右侧
            if ((pos.X + this.dgvGrid.Width) > this.TopLevelControl.ClientRectangle.Width)
                pos.X = (this.TopLevelControl.ClientRectangle.Width - this.dgvGrid.Width);

            this.dgvGrid.Location = pos;// this.Parent.PointToScreen(pt);
            this.dgvGrid.Parent = this.TopLevelControl;
            this.dgvGrid.Refresh();
            this.dgvGrid.BringToFront();
            this.dgvGrid.Visible = true;
            dropdown = true;

        }
        /// <summary>
        /// 
        /// </summary>
        private void DataBind()
        {
            DataSourceBind();
            dgvGrid.DataSource = _dataSourse;          
        }

       
    }
}
